import StringIO
import re

class Certificate():
	'''
		Die Klasse Certificate wird zum Parsen der Zertifikate genutzt. Durch diese Klasse werden
		die Informationen wie Public Key Algorithm, Common Name usw. ausgelesen. Die am Ende der Datei
		angegebenen Funktionen liefern die jeweilige Information zurueck. 
	'''
	def __init__(self):
		self.cert = {}
		
	def parse(self, certificate):
		buff = StringIO.StringIO(certificate)
		line = buff.readline()
		while line:
			pureLine = line#[0:len(line)-1]
				
			if pureLine.find("Not Before:") > -1:
				nbf = pureLine[pureLine.find("Not Before: ")+12:]
				self.cert["NBF"] = nbf.strip()
				line = buff.readline()
				continue
			
			if pureLine.find("Not After :") > -1:
				naf = pureLine[pureLine.find("Not After :")+11:]
				self.cert["NAF"] = naf.strip()
				line = buff.readline()
				continue
			
			if pureLine.find("Subject:") > -1:
				if pureLine.find("CN=") > -1:
					commonName = pureLine[pureLine.find("CN=")+3:]
					commonName = commonName.split(",")
					commonNameLst = []
					commonNameLst.append(commonName[0].strip())
					for c in commonName:
						if c.find("CN=") > -1:
							commonNameLst.append(c.strip()[3:])
					self.cert["CN"] = "|".join(commonNameLst)
					
			if pureLine.find("Public Key Algorithm:") > -1:
				pka = pureLine[pureLine.find("Public Key Algorithm: ")+22:].strip()
				self.cert["PKA"] = pka
				if pka == "rsaEncryption":
					# parse key length with kw RSA Public Key
					line = buff.readline()# line should contain RSA Public Key
					pureLine = line.strip()
					if pureLine.find("RSA Public Key:") > -1:
						keyLength = pureLine[pureLine.find("RSA Public Key: ")+ 16:].rstrip(" bit)").lstrip("(") 
						self.cert["KL"] = keyLength
						line = buff.readline()# Line should contain modulus
						pureLine = line.strip()
						if pureLine.find("Modulus") > -1:
							self.cert["Key"] = {} # key in this case is also a dict
							modulusLength = pureLine[pureLine.find("Modulus ")+9:].rstrip(" bit):").lstrip("(")
							self.cert["Key"]["ModLength"] = modulusLength
							modulusBuff = []
							line = buff.readline()
							while line.find("Exponent:") == -1: # as long as line does not contains "Exponent:"
								#modulusBuff.append(line.strip(" "))
								modulusBuff.append(line.strip())
								line = buff.readline()
							self.cert["Key"]["Modulus"]= ''.join(modulusBuff)
						# now parse the exponent of the key
						pureLine = line.strip()# because of the check in while, we do not need a check here
						exponent = pureLine[pureLine.find("Exponent: ")+10:].strip()
						sizePattern = re.compile(r"([0-9]+)")
						ext = sizePattern.match(exponent)
						self.cert["Key"]["Exponent"]=ext.group(0)
					pass 
				
			if pureLine.find("Signature Algorithm:") > -1:
				signatureAlgo = pureLine[pureLine.find(":")+2:].strip()
				self.cert["SA"] = signatureAlgo
				sigBuff = []
				line = buff.readline()
				while line.find(":") > -1:
					sigBuff.append(line.strip())
					line = buff.readline()
				self.cert["Sig"] = str( ((len("".join(sigBuff)) + 1 ) / 3)*8 )
				pass
			
				
			line = buff.readline()
				
	def getSA(self):
		return self.cert["SA"] 
	def getCN(self):
		return self.cert["CN"]
	def getNBF(self):
		return self.cert["NBF"]
	def getNAF(self):
		return self.cert["NAF"]
	def getPKA(self):
		return self.cert["PKA"]
	def getKL(self):
		return self.cert["KL"]
	def getModLen(self):#TODO check if Public Key is RSA before return ModLength
		return self.cert["Key"]["ModLength"]
	def getMod(self):#TODO check if Public Key is RSA before return Modulus
		return self.cert["Key"]["Modulus"]
	def getExp(self):
		return self.cert["Key"]["Exponent"]
	def getSL(self):
		return self.cert["Sig"]
	

if __name__ == "__main__":
	
	
	certString = file("telefonicaitaly.txt").read()
	#certString = file("sararf.txt").read()
	
	cert = Certificate()
	cert.parse(certString)
	print "Signature Algo   >>%s<<"% cert.getSA()
	print "Signature Length >>%s<<"% cert.getSL()
	print "Key length       >>%s<<"% cert.getKL()
	print "Public key algo  >>%s<<"% cert.getPKA()
	print "Common Name      >>%s<<"% cert.getCN()
	print "Not before       >>%s<<"% cert.getNBF()
	print "Not after        >>%s<<"% cert.getNAF()
	print "Mod length       >>%s<<"% cert.getModLen()
	print "Modulus          >>%s<<"% cert.getMod()
	print "Exponent         >>%s<<"% cert.getExp()
	
	
	
	
	
